package tetrinet.client;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.ImageElement;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.dom.client.MouseMoveEvent;
import com.google.gwt.event.dom.client.MouseMoveHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.ResourceCallback;
import com.google.gwt.resources.client.ResourceException;
import com.google.gwt.user.client.Random;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.Window.ClosingEvent;
import com.google.gwt.user.client.Window.ClosingHandler;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.Widget;

import gwt.g2d.client.graphics.KnownColor;
import gwt.g2d.client.graphics.Surface;
import gwt.g2d.client.graphics.TextBaseline;
import gwt.g2d.client.util.Cycle;
import gwt.g2d.client.util.FpsTimer;
import gwt.g2d.resources.client.ExternalImageResource;
import gwt.g2d.resources.client.ImageElementResource;

public class TetrinetGame extends FpsTimer implements SocketListener, ClosingHandler, CloseHandler<Window> {
	protected static final int WIDTH = 800, HEIGHT = 600;
	private final Surface surface;

	private float time = 0;
	private final int KEY_LEFT = 37;
	private final int KEY_UP = 38;
	private final int KEY_RIGHT = 39;
	private final int KEY_DOWN = 40;
	private ImageElement img;
	
	public static final int CUBE_BLUE = 0;
	public static final int CUBE_YELLOW = 1;
	public static final int CUBE_GREEN = 2;
	public static final int CUBE_PINK = 3;
	public static final int CUBE_RED = 4;
	public static final int CUBE_A = 5;
	public static final int CUBE_C = 6;
	public static final int CUBE_N = 7;
	public static final int CUBE_R = 8;
	public static final int CUBE_S = 9;
	public static final int CUBE_B = 10;
	public static final int CUBE_G = 11;
	public static final int CUBE_Q = 12;
	public static final int CUBE_O = 13;
	private final int CUBE_EMPTY = 14;
    
	private final int LARGE = 20;
	private final int SMALL = 10;
    
	private String[] player_names = new String[6];
	private TetrisMatrix[] player_boards2 = new TetrisMatrix[6];
	private String[] player_boards = new String[6];
	
	private Piece nextPiece;
	private Channel channel;
	private int player_id;
	private String player_name;
	private String room;
	
    void drawCube(int color, int size, int x, int y ){
        if( color != CUBE_EMPTY) {
            surface.drawImage(img,size*color,(size==SMALL)?LARGE:0,size,size,x,y,size,size);
        }
    }
    
    void drawNextPiece(Piece p) {
    	int start_x = 250;
    	int start_y = 5;
    	
    	surface.setFillStyle(KnownColor.BLACK);
    	surface.fillRectangle(start_x, start_y, 80, 80);
    	surface.setFillStyle(KnownColor.WHITE);
    	
    	for (int r = 0; r < Piece.PIECE_SIZE; r++) {
            for (int c = 0; c < Piece.PIECE_SIZE; c++) {
            	BlockType b = p.getBlock(r, c);
            	if( b == null)
            		continue;
            	drawCube(b.getColor(), LARGE, start_x+c*LARGE,start_y+r*LARGE);   
            }
    	}
    }
    
    //large 240x440
    //small 120x220
    void drawBackground(int x, int y, int size){
    	surface.drawImage(img,(size==SMALL)?240:0,30,12*size,22*size,x,y,12*size,22*size);
    }
    
    void drawBoard(int player, int x, int y, int size) {
    	TetrisMatrix matrix = player_boards2[player];
        drawBackground(x,y,size);
        
        for (int r = 0; r < matrix.getNumRows(); r++) {
            for (int c = 0; c < matrix.getNumCols(); c++) {
            	BlockType b = matrix.getBlock(r, c);
		        if( b == null )
		        	continue;
            	drawCube(b.getColor(), size, x+c*size,y+r*size);                       
            }
        }
    }
	
	public TetrinetGame(String channel, int player_id, String player_name, String[] known_players, String room){
		super(60);
		surface = new Surface(WIDTH, HEIGHT);
        this.channel = ChannelFactory.createChannel(channel);

	     // Open the channel and attach a listener.
	     this.channel.open(this);
	     this.player_id = player_id;
	     this.player_name = player_name;
	     this.player_names = known_players;
	     this.room = room;
	     send_command("JOIN "+player_id+"|"+player_name);
	}
	
	
	public void initialize() {
		surface.setWidth(800);
		surface.setHeight(600);
		nextPiece = new Piece();
		player_boards[0] = "ggaegcfalmidgncacmmlgdbnhagkmkaniagbjofmebnmdibiecbieabdoohbjblegnhjakjjkkfhfnomhajdfgjccmcimegfdlnoeomglddlbikboilkjkannlbheneeodhaeccclmhmnjfjddoiakelechfaifmiemfkbfjnalkaeamlkemaoiddgkolmdmncmfhlobkhjddklhmlmlhlfojicfmcnhnmnflkaflnfoldbdmaiobhfafngkgoeldjnoibmj";
        player_boards[1] = "lcolgglhddibeengdadbkdhlhjaceeiffiganfmeohkbbmckelhkbkkgdjmjfagjbgndollkomahjjejogknmcbgbljdlgnlkocghcjdkdjimfndmgobjldekigedhjcbjjndndnhdnfedbnghhkaglfdgnhnbfdihhegenmgiecanihdoeodoheiclhhmajgjkdlfahmmgmgclhdlegkfjnfaamnbggkemniabgbjefiedmddgfjngnbcogoghnkgkbdnmh";
        player_boards[2] = "dmongjnkgodhaffdhadcmjdniaieofcjkbihbigondhegdlmbmbbbdcmdnkddbleiojlbgannbiolghnjdnjahfoegmclcjldbjndmlbchflnalfjmfmancokjceajekdaelkjnlcdmdnijaodcjnbankdededbinhekeljbeoojaclcfeicmfnifbdmkbbaiiggnhlancmdjjffegimfoacoenjbfbcddnaohhedjefknhmdhddleanigibenkcjedncdhj";
        player_boards[3] = "cmojmkjfoionnfjndoibcmkhnhboealamonjbmeogabfinndiadblnokaenkokgdfloebkakaongngkglmogecihfliiefhhbljdfodnackfangicdnhmnnehikgihklimondejedlcbmjkofdeffijeoemjcojbmneijcmlhalmihnddmggjfejknomfbdhbhefonnfehojccbkdeicehiifafbdglbjdencfkghoojhjkkellfjnonobolemgejefleofm";
        player_boards[4] = "cmgmgmjkenjanbocmhjgfodihndjigllijkcbgbooifmkecffdihiilcefkokmgjjchmhhfkgcdahjeikagajdjfgdmbgcdbiekmfcnmkcbeodejnmoojaajoilojjnkkdjonfngcnnljlohdhakmikciegiebnaldacaacahbaeeiaonmemdnoakgnjacbhdgehakklcicloahbceecmegonlgdhmnilkjceknfhmcggfebkdhbcgieciecbbaegbhmjkfg";
        player_boards[5] = "kaigeocmkemmjnhhjlnofgajeojihdfbiccijkffgaomhbenfnccljfobacnfidgjefbehjmeefkieieljgjcfbolmaafkmbaioaoihbkoflgcfalenanmnlmfkoncjjbkdnaohefoagadfhgmblmneioamddfolnliboaeblbfagohminndfeekbojioojllfmofeibcbcenofdgoigbjghlkiaddkljlnniagecfbefoccgfflejddfaohjebcahmjkolj";
        player_boards2[0] = new TetrisMatrix(DEFAULT_NUM_ROWS, DEFAULT_NUM_COLS);
        player_boards2[1] = new TetrisMatrix(DEFAULT_NUM_ROWS, DEFAULT_NUM_COLS);
        player_boards2[2] = new TetrisMatrix(DEFAULT_NUM_ROWS, DEFAULT_NUM_COLS);
        player_boards2[3] = new TetrisMatrix(DEFAULT_NUM_ROWS, DEFAULT_NUM_COLS);
        player_boards2[4] = new TetrisMatrix(DEFAULT_NUM_ROWS, DEFAULT_NUM_COLS);
        player_boards2[5] = new TetrisMatrix(DEFAULT_NUM_ROWS, DEFAULT_NUM_COLS);
		
		Resources.INSTANCE.gwtLogo().getImage(new ResourceCallback<ImageElementResource>() {
            @Override
            public void onSuccess(ImageElementResource resource) {
            	img = resource.getImage();
            }
            @Override
            public void onError(ResourceException e) {
                Window.alert("Error: " + e.getMessage());
            }
    });
		initializeKeyHandlers();
		Window.addWindowClosingHandler(this);
		Window.addCloseHandler(this);
		surface.setFocus(true);
		
		
	}
	
	boolean chatting = false;
	
	 private void initializeKeyHandlers() {
         surface.addKeyDownHandler(new KeyDownHandler() {
                 @Override
                 public void onKeyDown(KeyDownEvent event) {
                	 	if( chatting ) {
                	 		if ( event.getNativeKeyCode() == 13){
                	 		 send_command("CHAT "+player_name+": "+input_chat);
                           	 chatting = false;
                           	input_chat = "";
                           	 return;
                            }
                	 		else if ( event.getNativeKeyCode() == 27){ 
                	 			input_chat = "";
                	 			chatting = false;
                              	 return;
                	 		}
                	 		else if ( event.getNativeKeyCode() == 8 ) {
                                input_chat = input_chat.substring(0,input_chat.length()-1);
                                event.preventDefault();
                                return;
                            }
                	 		else if ( event.getNativeKeyCode() >= 32 && event.getNativeKeyCode() <= 126) {
                	 			
                	 			if( event.getNativeKeyCode() >= 65 && event.getNativeKeyCode() <= 90 ) {
                	 				input_chat += (char)(event.getNativeKeyCode()+(event.isShiftKeyDown()?0:32))+"";
                	 			}
                	 			else if( event.isShiftKeyDown() ) {
                	 				if( event.getNativeKeyCode() == 48 ) {
                    	 				input_chat += ")";
                    	 			}
                    	 			else if( event.getNativeKeyCode() == 49 ) {
                    	 				input_chat += "!";
                    	 			}
                    	 			else if( event.getNativeKeyCode() == 50 ) {
                    	 				input_chat += "@";
                    	 			}
                    	 			else if( event.getNativeKeyCode() == 51 ) {
                    	 				input_chat += "#";
                    	 			}
                    	 			else if( event.getNativeKeyCode() == 52 ) {
                    	 				input_chat += "$";
                    	 			}
                    	 			else if( event.getNativeKeyCode() == 53 ) {
                    	 				input_chat += "%";
                    	 			}
                    	 			else if( event.getNativeKeyCode() == 54 ) {
                    	 				input_chat += "^";
                    	 			}
                    	 			else if( event.getNativeKeyCode() == 55 ) {
                    	 				input_chat += "&";
                    	 			}
                    	 			else if( event.getNativeKeyCode() == 56 ) {
                    	 				input_chat += "*";
                    	 			}
                    	 			else if( event.getNativeKeyCode() == 57 ) {
                    	 				input_chat += "(";
                    	 			}
                	 			}
                	 			else {
                	 				input_chat += (char)(event.getNativeKeyCode())+"";
                	 			}
                                return;
                            }
                	 		
                	 		return;
                	 	}
                	 
                	 
                         if (currPiece == null) {
                        	 if ( event.getNativeKeyCode() == 84){ 
                            	 chatting = true;
                             }
                        	 else if ( event.getNativeKeyCode() == 78 && event.isAltKeyDown()){ 
                            	 if( player_id == 0) {
                            		 send_command("STARTOVER");
                            	 }
                            	 else {
                            		 log("You cannot restart the game.You are not the 1st player.");
                            	 }
                            	 event.preventDefault();
                             }
                             return;
                         }
                         // Moves left or right.
                         int newCol = currCol;
                         int newRow = currRow;
                         if (event.isLeftArrow()) {
                                 newCol--;
                                 event.preventDefault();
                         } else if (event.isRightArrow()) {
                                 newCol++;
                                 event.preventDefault();
                         } else if (event.isDownArrow()) {
                                 newRow++;
                                 event.preventDefault();
                         } else if (event.isUpArrow()) {
                        	 TetrisMatrix matrix = player_boards2[player_id];
                             // Rotates the piece.
                             matrix.removePiece(currRow, currCol, currPiece);
                             currPiece.rotateRight();
                             if (!matrix.isValidPiece(currRow, currCol, currPiece)) {
                                     currPiece.rotateLeft();
                             } else {
                                     needRedraw = true;
                             }
                             matrix.setPiece(currRow, currCol, currPiece);
                             event.preventDefault();
                         } else if ( event.getNativeKeyCode() >= 49 && event.getNativeKeyCode() <= 54){ 
                        	 BlockType b = specialBlocksAcquired.remove(0);
                        	 int player = event.getNativeKeyCode();
                        	 send_command("SPECIAL "+player_id+"|"+(player-49)+"|"+b);
                         }
                         else if ( event.getNativeKeyCode() == 32){ // press space to drop
                        	int testRow = currRow;
                        	
                        	TetrisMatrix matrix = player_boards2[player_id];
							matrix .removePiece(currRow, currCol, currPiece);
                        	
							testRow++;
                        	while(matrix.isValidPiece(testRow, currCol, currPiece)) {
                        		testRow++;
                        	}
                        	// Hits the ground, stopping.
                        	testRow--;
     		                matrix.setPiece(testRow, currCol, currPiece);
     		                Tuple2<Integer,List<BlockType>> t = matrix.checkAndClear(testRow + Piece.PIECE_SIZE);
     		                int rowsCleared = t.item1;
     		                List<BlockType> specialBlocksAcquired = t.item2;
     		                if (rowsCleared > 0) {
     		                		matrix.addSpecialBlocks(rowsCleared);
     		                		addSpecialBlocks(specialBlocksAcquired);
     		                }
     		                send_board_update();
     		                currPiece = null;
     		                if( testRow == 0) {
     		                	//Game over
     		                	gameOver = true;
     		                	send_command("GAMEOVER "+player_id);
     		                }
                         }
                         else if ( event.getNativeKeyCode() == 68){ 
                        	 specialBlocksAcquired.remove(0);
                         } 
                         else if ( event.getNativeKeyCode() == 84){ 
                        	 chatting = true;
                         }
                         else if ( event.getNativeKeyCode() == 78 && event.isAltKeyDown()){ 
                        	 if( player_id == 0) {
                        		 send_command("STARTOVER");
                        	 }
                        	 else {
                        		 log("You cannot restart the game.You are not the 1st player.");
                        	 }
                        	 event.preventDefault();
                         }
                         else {
                                return;
                         }
                         TetrisMatrix matrix = player_boards2[player_id];
                         matrix.removePiece(currRow, currCol, currPiece);
                         if (matrix.isValidPiece(newRow, newCol, currPiece)) {
                                 currRow = newRow;
                                 currCol = newCol;
                                 needRedraw = true;
                         }
                         matrix.setPiece(currRow, currCol, currPiece);
                 }

         });
 }
	 
	 List<String> gameLog = new ArrayList<String>();
	 
	 private void log(String s) {
		 gameLog.add(s);
		 if(gameLog.size()>13) {
			 gameLog.remove(0);
		 }
	}
	 
	 List<String> chat = new ArrayList<String>();
	 String input_chat = "";
	 
	 private void chat(String s) {
		 chat.add(s);
		 if(chat.size()>12) {
			 chat.remove(0);
		 }
	}
	 
	 private void send_command(String s) {
		 RequestBuilder rb = new RequestBuilder(RequestBuilder.POST,
		 "/chat?key="+room);
		try
		{
		    rb.sendRequest(s, new RequestCallback() {
				
				@Override
				public void onResponseReceived(Request request, Response response) {
				}
				
				@Override
				public void onError(Request request, Throwable exception) {
					Window.alert(exception.toString());
				}
			});
		                         
		}
		catch (RequestException e) {
		    Window.alert(e.toString());
		}
	 }
	
	
	@Override
	public void update() {
		float delta = 1.0f/this.getFps();
		if( !Float.isInfinite(delta) && !Float.isNaN(delta) ) {
			draw(delta);
			time += delta;
		}
	}

    private static final int DEFAULT_NUM_ROWS = 22, DEFAULT_NUM_COLS = 12;
    private static final int DEFAULT_START_ROW = 0, 
                    DEFAULT_START_COL = DEFAULT_NUM_COLS / 2 - Piece.PIECE_SIZE / 2;
	
	private Piece currPiece;
	
	private int currRow, currCol;
 
    private int level;
    private int totalRowsCleared;
    private int levelOffset = 0;
    private boolean needRedraw = true, needRedrawNextPiece = true;
	
    float row_per_second = 48.0f/60.0f;
    float counter = 0;
	private boolean gameOver;
    
	private void draw(float delta) {
		surface.fillBackground(KnownColor.BLACK);
		
		if( !gameOver ) {
			TetrisMatrix matrix = player_boards2[player_id];
			if (currPiece == null) {
	            currPiece = nextPiece;
	            nextPiece = new Piece();
	            drawNextPiece(nextPiece);
	            currRow = DEFAULT_START_ROW;
	            currCol = DEFAULT_START_COL;
	            matrix.setPiece(currRow, currCol, currPiece);
	            needRedrawNextPiece = true;
	            needRedraw = true;
		    }
		    
			
			if( counter > row_per_second) 
			{
				matrix.removePiece(currRow, currCol, currPiece);
		        currRow++;
		        if (matrix.isValidPiece(currRow, currCol, currPiece)) {
		                matrix.setPiece(currRow, currCol, currPiece);
		                needRedraw = true;
		        } else {
		                // Hits the ground, stopping.
		                currRow--;
		                matrix.setPiece(currRow, currCol, currPiece);
		                Tuple2<Integer,List<BlockType>> t = matrix.checkAndClear(currRow + Piece.PIECE_SIZE);
		                int rowsCleared = t.item1;
		                List<BlockType> specialBlocksAcquired = t.item2;
		                if (rowsCleared > 0) {
		                		matrix.addSpecialBlocks(rowsCleared);
		                		addSpecialBlocks(specialBlocksAcquired);
		                }
		                send_board_update();
		                currPiece = null;
		                if( currRow == 0) {
		                	//Game over
		                	gameOver = true;
		                	send_command("GAMEOVER "+player_id);
		                }
		        }
		        counter = 0;
			}
		}
		
		counter += delta;
		
		surface.setFillStyle(KnownColor.WHITE);
        surface.setFont("10px sans-serif");
        surface.setTextBaseline(TextBaseline.TOP);
		drawBoard(player_id,5,5,LARGE);
		surface.fillText((player_id+1)+". "+player_name, 5, 5);
		
		int j = 0;
		if( player_id == j) j++;
		drawBoard(j,425,5,SMALL);
		surface.fillText((j+1)+". "+player_names[j], 425,5);
		
		j++;
		if( player_id == j) j++;
        drawBoard(j,550,5,SMALL);
        surface.fillText((j+1)+". "+player_names[j], 550,5);
        
        j++;
		if( player_id == j) j++;
        drawBoard(j,675,5,SMALL);
        surface.fillText((j+1)+". "+player_names[j], 675,5);
        
        j++;
		if( player_id == j) j++;
        drawBoard(j,550,230,SMALL);
        surface.fillText((j+1)+". "+player_names[j], 550,230);
        
        j++;
		if( player_id == j) j++;
        drawBoard(j,675,230,SMALL);
        surface.fillText((j+1)+". "+player_names[j], 675,230);
        
        for( int i = gameLog.size()-1 ; i >= 0 ; i--) {
        	surface.fillText(gameLog.get(gameLog.size()-1-i), 250,225+i*10,100);
        }
        
        for( int i = chat.size()-1 ; i >= 0 ; i--) {
        	surface.fillText(chat.get(chat.size()-1-i), 5,450+i*10);
        }
        
        if( chatting ) {
        	surface.setFillStyle(KnownColor.DARK_GREEN);
        	surface.fillRectangle(0,580,800,20);
        	surface.setFillStyle(KnownColor.WHITE);
        	surface.fillText(input_chat, 5,585);
        }
        
        drawNextPiece(nextPiece);
        
        drawSpecialBlocks();
        
	}
	

	 
	 
	private void send_board_update() {
		send_command("UPDATE "+player_id+"|"+player_boards2[player_id].getAsString());
	}

	private void drawSpecialBlocks() {
		int start_x = 250, start_y = 420;
		
		for(int i = 0 ; i < specialBlocksAcquired.size() || i < 10; i++) {
			drawCube(specialBlocksAcquired.get(i).getColor(), LARGE, start_x+i*LARGE, start_y);
		}
	}



	public String join(List<String> coll, String delimiter)
	{
	    if (coll.isEmpty())
		return "";
	 
	    StringBuilder sb = new StringBuilder();
	 
	    for (String x : coll)
		sb.append(x + delimiter);
	 
	    sb.delete(sb.length()-delimiter.length(), sb.length());
	 
	    return sb.toString();
	}

	List<BlockType> specialBlocksAcquired = new ArrayList<BlockType>();
	private void addSpecialBlocks(List<BlockType> blocks) {
		specialBlocksAcquired.addAll(blocks);
	}

	interface Resources extends ClientBundle {
        static final Resources INSTANCE = GWT.create(Resources.class);

        @Source("/blocks.png")
        ExternalImageResource gwtLogo();
	}

	public Widget getSurface() {
		return surface;
	}



	@Override
	public void onOpen() {
		chat("Connection opened ...");
	}

	public static final native String[] split(String string, String separator) /*-{
    return string.split(separator);
}-*/;

	@Override
	public void onMessage(String message) {
		if( message.startsWith("CHAT ")) {
			chat(message.substring(5));
		}
		else if( message.startsWith("SPECIAL ")) {
			String[] c = split(message.substring(8),"|");
			int source_player = Integer.parseInt(c[0]);
			int destination_player = Integer.parseInt(c[1]);
			String special_block = c[2];
			
			if(destination_player == player_id) {
				player_boards2[player_id].removePiece(currRow, currCol, currPiece);
				if(special_block == "ADD_LINE"){
					player_boards2[player_id].addLine();
				}
				else if(special_block == "REMOVE_SPECIAL_BLOCKS"){
					player_boards2[player_id].removeSpecialBlocks();
				}
				else if(special_block == "CLEAR_LINE"){
					player_boards2[player_id].clearLine();
				}
				else if(special_block == "GRAVITY"){
					player_boards2[player_id].blockGravity();
					Tuple2<Integer,List<BlockType>> t = player_boards2[player_id].checkAndClear(DEFAULT_NUM_ROWS-1);
	                int rowsCleared = t.item1;
	                List<BlockType> specialBlocksAcquired = t.item2;
	                if (rowsCleared > 0) {
	                		addSpecialBlocks(specialBlocksAcquired);
	                }
				}
				else if(special_block == "BLOCK_QUAKE"){
					player_boards2[player_id].blockQuake();
				}
				else if(special_block == "RANDOM_BLOCK_CLEAR"){
					player_boards2[player_id].randomBlockClear();
				}
				else if(special_block == "SWITCH_FIELDS"){
					String myBoard = player_boards2[player_id].getAsString();
					String enemyBoard = player_boards2[destination_player].getAsString();
					player_boards2[player_id].updateFromString(enemyBoard);
					send_command("FORCEUPDATE "+destination_player+"|"+myBoard);
				}
				else if(special_block == "BLOCK_BOMB"){
					player_boards2[player_id].blockBomb();
				}
				else if(special_block == "NUKE_FIELD"){
					player_boards2[player_id].nukeField();
				}
				player_boards2[player_id].setPiece(currRow, currCol, currPiece);
				send_board_update();
			}
			
			log("Player "+(source_player+1)+" used "+special_block+" on player "+(destination_player+1));
		}
		else if( message.startsWith("JOIN ")) {
			String[] c = split(message.substring(5),"|");
			int j = Integer.parseInt(c[0]);
			player_names[j] = c[1];
		}
		else if( message.startsWith("UPDATE ")) {
			String[] c = split(message.substring(7),"|");
			int j = Integer.parseInt(c[0]);
			if( j != player_id) {
				player_boards2[j].updateFromString(c[1]);
			}
		}
		else if( message.startsWith("FORCEUPDATE ")) {
			String[] c = split(message.substring(12),"|");
			int j = Integer.parseInt(c[0]);
			if( j == player_id) {
				player_boards2[j].updateFromString(c[1]);
			}
		}
		else if( message.startsWith("GAMEOVER ")) {
			int j = Integer.parseInt(message.substring(9));
			log("Player "+(j+1)+" lost.");
		}
		else if( message.startsWith("STARTOVER")) {
			for(int i=0 ; i < 6 ; i++) {
				player_boards2[i].clearBoard();
			}
			gameOver = false;
			currPiece = null;
			log("Starting new game.");
		}
	}

	@Override
	public void onWindowClosing(ClosingEvent event) {
		event.setMessage("Are you sure you want to quit your tetrinet game?");
	}

	@Override
	public void onClose(CloseEvent<Window> event) {
		send_command("GAMEOVER "+player_id);
	}
}
